package com.lanp.gencode.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.lanp.gencode.ToApiMain;
import com.lanp.gencode.config.JavaCSV;
import com.lanp.gencode.config.LanpException;
import com.lanp.gencode.fileInfo.FileInfo;
import com.lanp.gencode.utils.DateUtils;
import com.lanp.gencode.utils.DocUtil;
import com.lanp.gencode.utils.SigoListUtils;
import com.lanp.gencode.utils.SigoStrUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

public class GenApiService {
    /**
     * bean文件对象的名称
     */
    private String BeanFileName,
    /**
     * 无前缀的 bean文件对象的名称
     */
    notPrefixBeanFileName,
    /**
     * dto文件对象的名称
     */
    DtoFileName,
    /**
     * 返回值dto文件对象的名称
     */
    ResDtoFileName,
    /**
     * dao层文件的对象名称
     */
    DaoFileName,
    /**
     * 项目包的文件路径
     */
    PackageFileUrl,
    /**
     * 项目包的文件路径
     */
    ExampleFileName;

    private List<FileInfo> controllerFileInfoList = new ArrayList<>();//控制层
    private List<FileInfo> interfaceFileInfoList = new ArrayList<>();//接口
    private List<FileInfo> serviceFileInfoList = new ArrayList<>();//接口实现类

    /* -------------------------- 当前支持的文件级别 ------------------------- */
    private FileInfo interface_file;
    private FileInfo service_file;
    private FileInfo controller_file;

    public List<FileInfo> initFileInfo() {
        List<FileInfo> resFileInfo = new ArrayList<>();
        String[] beanS = ToApiMain.BeanFile.split("\\.");
        BeanFileName = beanS[beanS.length - 1];
        notPrefixBeanFileName = BeanFileName.substring(ToApiMain.Prefix.length());
        String[] dtoS = ToApiMain.DtoFile.split("\\.");
        DtoFileName = dtoS[dtoS.length - 1];
        String[] resDtoS = ToApiMain.ResDtoFile.split("\\.");
        ResDtoFileName = resDtoS[resDtoS.length - 1];
        String[] daoS = ToApiMain.DaoFile.split("\\.");
        DaoFileName = daoS[daoS.length - 1];
        String[] exampleS = ToApiMain.BeanExampleFile.split("\\.");
        ExampleFileName = exampleS[exampleS.length - 1];
        StringTokenizer beanST = new StringTokenizer(ToApiMain.BeanFile, ".");
        StringTokenizer dtoST = new StringTokenizer(ToApiMain.DtoFile, ".");
        StringTokenizer daoST = new StringTokenizer(ToApiMain.DaoFile, ".");
        StringTokenizer packageFileUrlST = new StringTokenizer(ToApiMain.ServicePackageUrl, ".");
        StringBuilder pksb = new StringBuilder(ToApiMain.ProjectUrl);
        while (packageFileUrlST.hasMoreTokens()) {
            pksb.append("/");
            pksb.append(packageFileUrlST.nextToken());
        }
        PackageFileUrl = pksb.toString();
        return resFileInfo;
    }

    /**
     * 获取常用导入包
     *
     * @return
     */
    public List<String> getCommonImport(String... imps) {
        List<String> res = SigoListUtils.toList("import java.util.List",
                "import java.util.Map");
        res.addAll(SigoListUtils.toList(imps));
        return res;
    }


    /**
     * 初始化生成需要的file文件
     */
    public void genClassFileInfo() {
        /* -------------------------- 生成接口 ------------------------- */
        interface_file = new FileInfo();
        interface_file.setAuthorInfo(ToApiMain.BeanChineseName + "业务接口");
        interface_file.setClassName(this.notPrefixBeanFileName + "Service");
        interface_file.setJavaType(JavaCSV.Java_Type_interface);
        interface_file.setPackageName(ToApiMain.ServicePackageUrl);
        interface_file.setImportList(getCommonImport("import " + ToApiMain.DtoFile
                , "import " + ToApiMain.ResDtoFile
                , "import " + ToApiMain.BeanFile
                , "import " + ToApiMain.resPageFile
        ));
        interface_file.setMethodInfoList(new ArrayList<>());
        interfaceFileInfoList.add(interface_file);
        /* -------------------------- 生成业务实现类 ------------------------- */
        service_file = new FileInfo();
        service_file.setJavaType(JavaCSV.Java_Type_class);
        service_file.setAuthorInfo(ToApiMain.BeanChineseName + "业务方法实现类");
        service_file.setPackageName(ToApiMain.ServicePackageUrl + ".impl");
        service_file.setImportList(getCommonImport("import " + ToApiMain.DtoFile
                , "import " + ToApiMain.ResDtoFile
                , "import " + ToApiMain.BeanFile
                , "import " + ToApiMain.DaoFile
                , "import " + ToApiMain.BeanExampleFile
                , "import " + ToApiMain.resPageFile
                , "import " + ToApiMain.ServicePackageUrl + "." + interface_file.getClassName()
                , "import " + ToApiMain.ProjectJavaUrl + ".util.SiGoBeanUtil"
                , "import org.apache.commons.lang3.StringUtils"
                , "import com.github.pagehelper.Page"
                , "import org.springframework.beans.factory.annotation.Autowired"
                , "import com.github.pagehelper.PageHelper"
                , "import org.springframework.stereotype.Service"
                , "import lombok.extern.slf4j.Slf4j"
        ));
        service_file.setImplClassName(interface_file.getClassName());
        service_file.setClassName(interface_file.getClassName() + "Impl");
        service_file.setClassAnnotations(SigoListUtils.toList(
                "@Service"
                , "@Slf4j"
        ));
        service_file.setFieldInfoList(new ArrayList<>());
        service_file.setMyMapperField(FileInfo.autoField(this.DaoFileName));
        service_file.setMethodInfoList(new ArrayList<>());
        serviceFileInfoList.add(service_file);
        /* -------------------------- 生成控制层api ------------------------- */
        String router = StrUtil.toSymbolCase(this.notPrefixBeanFileName, '-');
        controller_file = new FileInfo();
        controller_file.setAuthorInfo(ToApiMain.BeanChineseName + "控制层API");
        controller_file.setJavaType(JavaCSV.Java_Type_class);
        controller_file.setPackageName(ToApiMain.ControllerPackageUrl);
        controller_file.setClassName(notPrefixBeanFileName + "Controller");
        controller_file.setClassAnnotations(SigoListUtils.toList(
                "@RestController"
                , "@Slf4j"
                , "@RequestMapping(\"/" + router + "\")"
        ));
        controller_file.setFieldInfoList(new ArrayList<>());
        controller_file.setMethodInfoList(new ArrayList<>());
        controller_file.setMyServiceField(FileInfo.autoField(interface_file.getClassName()));
        controller_file.setImportList(getCommonImport("import " + ToApiMain.DtoFile
                , "import " + ToApiMain.ResDtoFile
                , "import " + ToApiMain.BeanFile
                , "import " + ToApiMain.DaoFile
                , "import " + interface_file.getPackageName() + "." + interface_file.getClassName()
                , "import " + ToApiMain.resPageFile
                , "import org.apache.commons.lang3.StringUtils"
                , "import org.springframework.beans.factory.annotation.Autowired"
                , "import org.springframework.web.bind.annotation.*"
                , "import lombok.extern.slf4j.Slf4j"
        ));
        controllerFileInfoList.add(controller_file);
    }

    /* -------------------------- list方法 ------------------------- */

    /**
     * 生成list api
     */
    public void genList() {
        interface_file.getMethodInfoList().add(iGenListMethod());
        service_file.getMethodInfoList().add(sGenListMethod());
        controller_file.getMethodInfoList().add(cGenListMethod());
    }

    /**
     * 生成控制层接口
     *
     * @return
     */
    public FileInfo.MethodInfo cGenListMethod() {
        FileInfo.MethodInfo methodList = new FileInfo.MethodInfo();
        methodList.setMethodName("list");
        methodList.setInParams(SigoListUtils.toList(this.DtoFileName));
        methodList.setRefundType("PageDataInfo<" + this.ResDtoFileName + ">");
        methodList.setMethodRemark(ToApiMain.BeanChineseName + "列表");
        methodList.setIsRouter(true);
        //获取内容
        StringBuilder mesb = new StringBuilder();
        mesb.append("        return ${varService}.list(${inParams});\n");
        methodList.setMethodContext(mesb.toString());
        return methodList;
    }

    /**
     * 生成业务接口类
     *
     * @return
     */
    public FileInfo.MethodInfo iGenListMethod() {
        FileInfo.MethodInfo methodList = new FileInfo.MethodInfo();
        methodList.setMethodName("list");
        methodList.setInParams(SigoListUtils.toList(this.DtoFileName));
        methodList.setRefundType("PageDataInfo<" + this.ResDtoFileName + ">");
        methodList.setMethodRemark(ToApiMain.BeanChineseName + "列表");
        //获取内容
        return methodList;
    }

    /**
     * 生成业务实现类
     *
     * @return
     */
    public FileInfo.MethodInfo sGenListMethod() {
        service_file.getImportList().add("import cn.hutool.core.collection.CollectionUtil");
        FileInfo.MethodInfo listMethod = new FileInfo.MethodInfo();
        listMethod.setMethodName("list");
        listMethod.setInParams(SigoListUtils.toList(this.DtoFileName));
        listMethod.setRefundType("PageDataInfo<" + this.ResDtoFileName + ">");
        StringBuilder mesb = new StringBuilder();
        mesb.append("        if (${inParams}.getPage()) {\n" +
                "            PageHelper.startPage(${inParams}.getPageNum(), ${inParams}.getPageSize(), true);\n" +
                "        }\n");
        mesb.append("        ${example} example = new ${example}();\n" +
                "        ${example}.Criteria criteria = example.createCriteria();\n");
        //假删状态
        mesb.append("        //判断假删\n" +
                "        criteria.andAvailableEqualTo(true);\n");
        //常用筛选项
        mesb.append("        //判断主键\n" +
                "        if (${inParams}.get${KeyName}() != null) {\n" +
                "            criteria.and${KeyName}EqualTo(${inParams}.get${KeyName}());\n" +
                "        }\n");
        mesb.append("        //判断主键列表\n" +
                "        if (CollectionUtil.isNotEmpty(${inParams}.get${KeyName}s())) {\n" +
                "            criteria.and${KeyName}In(${inParams}.get${KeyName}s());\n" +
                "        }\n");
        //拼接其他筛选项
        List<DocUtil.VoDoc> beanDocs = DocUtil.JavaToDoc(
                ToApiMain.ProjectUrl + "/" + (ToApiMain.DtoFile.replaceAll("\\.", "/")) + ".java");
        for (DocUtil.VoDoc beanDoc : beanDocs) {
            if (beanDoc.getFieldName().equals(ToApiMain.KeyName) || beanDoc.getFieldName().equals(ToApiMain.KeyName + "s")) {
                continue;//主键，不重复生成
            }
            String remark = beanDoc.getCommentText().replaceAll("\n", "").replaceAll("\r\n", "");
            mesb.append("        //判断" + remark + "\n");
            String getMethodName = SigoStrUtils.getGetMethodName(beanDoc.getFieldName());
            switch (beanDoc.getFieldType()) {
                case "String":
                    mesb.append("        if(StringUtils.isNotBlank(${inParams}.get" + getMethodName + "())){\n" +
                            "            criteria.and" + getMethodName + "EqualTo(${inParams}.get" + getMethodName + "());\n" +
                            "        }\n");
                    break;
                case "List":
                    String getMethodNamePJ = getMethodName;
                    char s = getMethodName.charAt(getMethodName.length() - 1);
                    if (s == 's' || s == 'S') {
                        getMethodNamePJ = getMethodName.substring(0, getMethodName.length() - 1);
                    }
                    mesb.append("        if (${inParams}.get" + getMethodName + "() != null) {\n" +
                            "            criteria.and" + getMethodNamePJ + "In(${inParams}.get" + getMethodName + "());\n" +
                            "        }\n");
                    break;
                default:
                    mesb.append("        if (${inParams}.get" + getMethodName + "() != null) {\n" +
                            "            criteria.and" + getMethodName + "EqualTo(${inParams}.get" + getMethodName + "());\n" +
                            "        }\n");
                    break;
            }
        }
        mesb.append("\t\texample.setOrderByClause(\"${key_name} desc\");\n");
        mesb.append("\t\tList<${beanName}> dbs = ${varMapper}.selectByExample(example);\n");
        mesb.append("\t\tPageDataInfo<${resDtoName}> resPage = new PageDataInfo<>();\n");
        mesb.append("\t\tif (${inParams}.getPage()) {\n" +
                "            Page<${beanName}> pageInfo = (Page<${beanName}>) dbs;\n" +
                "            resPage.setTotal_count(pageInfo.getTotal());\n" +
                "            resPage.setPage_num(pageInfo.getPageNum());\n" +
                "            resPage.setPage_size(pageInfo.getPageSize());\n" +
                "        }\n");
        mesb.append("\t\tresPage.setPage_data(SiGoBeanUtil.copyList(dbs, ${resDtoName}.class));\n" +
                "        return resPage;\n");
        //获取内容
        listMethod.setMethodContext(mesb.toString());
        return listMethod;
    }
    /* -------------------------- 添加方法 ------------------------- */

    /**
     * 生成add api
     */
    public void genAdd() {
        interface_file.getMethodInfoList().add(iGenAddMethod());
        service_file.getMethodInfoList().add(sGenAddMethod());
        controller_file.getMethodInfoList().add(cGenAddMethod());
    }

    /**
     * 生成控制层接口
     *
     * @return
     */
    public FileInfo.MethodInfo cGenAddMethod() {
        FileInfo.MethodInfo c_method = new FileInfo.MethodInfo();
        c_method.setMethodName("add");
        c_method.setIsRouter(true);
        c_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        c_method.setRefundType("Integer");
        c_method.setMethodRemark("添加一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        StringBuilder mesb = new StringBuilder();
        mesb.append("        return ${varService}.add(${inParams});\n");
        c_method.setMethodContext(mesb.toString());
        return c_method;
    }

    /**
     * 生成业务接口类
     *
     * @return
     */
    public FileInfo.MethodInfo iGenAddMethod() {
        FileInfo.MethodInfo i_method = new FileInfo.MethodInfo();
        i_method.setMethodName("add");
        i_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        i_method.setRefundType("Integer");
        i_method.setMethodRemark("添加一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        return i_method;
    }

    /**
     * 生成业务实现类
     *
     * @return
     */
    public FileInfo.MethodInfo sGenAddMethod() {

        //添加需要使用的bean
        //service_file.getFieldInfoList().add(FileInfo.autoField("UidGenService"));
        //service_file.getImportList().add("import " + ToApiMain.ServicePackageUrl + ".UidGenService");
        service_file.getImportList().add("import java.util.Date");

        FileInfo.MethodInfo s_Method = new FileInfo.MethodInfo();
        s_Method.setMethodName("add");
        s_Method.setInParams(SigoListUtils.toList(this.DtoFileName));
        s_Method.setRefundType("Integer");
        StringBuilder mesb = new StringBuilder();
        if (ToApiMain.TimeData) {
            mesb.append("        Date nowDateObj = new Date();\n");
            mesb.append("        Long nowDate = nowDateObj.getTime();\n");
        } else {
            mesb.append("        Date nowDate = new Date();\n");
        }
        mesb.append("        ${beanName} in_bean = SiGoBeanUtil._copyToBean(${inParams}, ${beanName}.class);\n");
        //设置id
        mesb.append("        in_bean.set${KeyName}(uidGenService.getNextId());\n");
        mesb.append("        in_bean.setCreateUser(${inParams}.getCurrentAccountName());\n" +
                "        in_bean.setModUser(${inParams}.getCurrentAccountName());\n" +
                "        in_bean.setCreateTime(nowDate);\n" +
                "        in_bean.setModTime(nowDate);\n" +
                "        in_bean.setAvailable(true);\n"
        );
        mesb.append("        return ${varMapper}.insertSelective(in_bean);\n");
        //获取内容
        s_Method.setMethodContext(mesb.toString());
        return s_Method;
    }

    /**
     * 生成update api
     */
    public void genEdit() {
        interface_file.getMethodInfoList().add(iGenEditMethod());
        service_file.getMethodInfoList().add(sGenEditMethod());
        controller_file.getMethodInfoList().add(cGenEditMethod());
    }

    /**
     * 生成控制层接口
     *
     * @return
     */
    public FileInfo.MethodInfo cGenEditMethod() {
        FileInfo.MethodInfo c_method = new FileInfo.MethodInfo();
        c_method.setMethodName("edit");
        c_method.setIsRouter(true);
        c_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        c_method.setRefundType("Integer");
        c_method.setMethodRemark("编辑一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        StringBuilder mesb = new StringBuilder();
        mesb.append("        /* --------- 校验${BeanChineseName}信息 --------- */\n");
        mesb.append("        if (${inParams}.get${KeyName}() == null || ${inParams}.get${KeyName}().longValue() < 1) {\n");
        mesb.append("            return SigoResult.fail(\"${BeanChineseName}ID不能为空\");\n");
        mesb.append("        }\n");
        mesb.append("        /* --------- 查询详情信息，进行一些权限校验 --------- */\n");
        mesb.append("        ${resDtoName} detail = ${varService}.Detail(${inParams});\n");
        mesb.append("        if (detail == null || !detail.getAvailable()) {\n");
        mesb.append("            return SigoResult.fail(\"${BeanChineseName}不存在或已删除\");\n");
        mesb.append("        }\n");
        mesb.append("        return ${varService}.edit(${inParams});\n");
        c_method.setMethodContext(mesb.toString());
        return c_method;
    }

    /**
     * 生成业务接口类
     *
     * @return
     */
    public FileInfo.MethodInfo iGenEditMethod() {
        FileInfo.MethodInfo i_method = new FileInfo.MethodInfo();
        i_method.setMethodName("edit");
        i_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        i_method.setRefundType("Integer");
        i_method.setMethodRemark("编辑一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        return i_method;
    }

    /**
     * 生成业务实现类
     *
     * @return
     */
    public FileInfo.MethodInfo sGenEditMethod() {

        //添加需要使用的bean
        //service_file.getFieldInfoList().add(FileInfo.autoField("UidGenService"));
        //service_file.getImportList().add("import " + ToApiMain.ServicePackageUrl + ".UidGenService");
        service_file.getImportList().add("import java.util.Date");

        FileInfo.MethodInfo s_Method = new FileInfo.MethodInfo();
        s_Method.setMethodName("edit");
        s_Method.setInParams(SigoListUtils.toList(this.DtoFileName));
        s_Method.setRefundType("Integer");
        StringBuilder mesb = new StringBuilder();
        if (ToApiMain.TimeData) {
            mesb.append("        Long nowDate = System.currentTimeMillis();\n");
        } else {
            mesb.append("        Date nowDate = new Date();\n");
        }
        mesb.append("        ${beanName} up_bean = SiGoBeanUtil._copyToBean(${inParams}, ${beanName}.class);\n");
        //设置id
        mesb.append("        up_bean.setModTime(nowDate);\n" +
                "        up_bean.setModUser(${inParams}.getCurrentAccountName());\n" +
                "        up_bean.setAvailable(true);\n"
        );
        mesb.append("        return ${varMapper}.updateByPrimaryKeySelective(up_bean);\n");
        //获取内容
        s_Method.setMethodContext(mesb.toString());
        return s_Method;
    }

    /**
     * 生成del api
     */
    public void genDel() {
        interface_file.getMethodInfoList().add(iGenDelMethod());
        service_file.getMethodInfoList().add(sGenDelMethod());
        controller_file.getMethodInfoList().add(cGenDelMethod());
    }

    /**
     * 生成detail api
     */
    public void genDetail() {
        interface_file.getMethodInfoList().add(iGenDetailMethod());
        service_file.getMethodInfoList().add(sGenDetailMethod());
        controller_file.getMethodInfoList().add(cGenDetailMethod());
    }

    /* -------------------------- del ------------------------- */

    /**
     * 生成控制层接口
     *
     * @return
     */
    public FileInfo.MethodInfo cGenDelMethod() {
        FileInfo.MethodInfo c_method = new FileInfo.MethodInfo();
        c_method.setMethodName("del");
        c_method.setIsRouter(true);
        c_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        c_method.setRefundType("Integer");
        c_method.setMethodRemark("删除一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        StringBuilder mesb = new StringBuilder();
        mesb.append("        /* --------- 校验${BeanChineseName}信息 --------- */\n");
        mesb.append("        if (${inParams}.get${KeyName}() == null || ${inParams}.get${KeyName}().longValue() < 1) {\n");
        mesb.append("            return SigoResult.fail(\"${BeanChineseName}ID不能为空\");\n");
        mesb.append("        }\n");
        mesb.append("        /* --------- 查询详情信息，进行一些权限校验 --------- */\n");
        mesb.append("        ${resDtoName} detail = ${varService}.Detail(${inParams});\n");
        mesb.append("        if (detail == null || !detail.getAvailable()) {\n");
        mesb.append("            return SigoResult.fail(\"${BeanChineseName}不存在或已删除\");\n");
        mesb.append("        }\n");
        mesb.append("        return ${varService}.del(${inParams});\n");
        c_method.setMethodContext(mesb.toString());
        return c_method;
    }

    /**
     * 生成业务接口类
     *
     * @return
     */
    public FileInfo.MethodInfo iGenDelMethod() {
        FileInfo.MethodInfo i_method = new FileInfo.MethodInfo();
        i_method.setMethodName("del");
        i_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        i_method.setRefundType("Integer");
        i_method.setMethodRemark("删除一个" + ToApiMain.BeanChineseName + "对象");
        //获取内容
        return i_method;
    }

    /**
     * 生成业务实现类
     *
     * @return
     */
    public FileInfo.MethodInfo sGenDelMethod() {

        //添加需要使用的bean
        //service_file.getFieldInfoList().add(FileInfo.autoField("UidGenService"));
        service_file.getImportList().add("import " + ToApiMain.ServicePackageUrl + ".UidGenService");
        service_file.getImportList().add("import java.util.Date");

        FileInfo.MethodInfo s_Method = new FileInfo.MethodInfo();
        s_Method.setMethodName("del");
        s_Method.setInParams(SigoListUtils.toList(this.DtoFileName));
        s_Method.setRefundType("Integer");
        StringBuilder mesb = new StringBuilder();
        if (ToApiMain.TimeData) {
            mesb.append("        Long nowDate = System.currentTimeMillis();\n");
        } else {
            mesb.append("        Date nowDate = new Date();\n");
        }
        mesb.append("        ${beanName} del_bean = SiGoBeanUtil._copyToBean(${inParams}, ${beanName}.class);\n");
        //设置id
        mesb.append("        del_bean.setDelTime(nowDate);\n" +
                "        del_bean.setDelUser(${inParams}.getCurrentAccountName());\n" +
                "        del_bean.setAvailable(false);\n"
        );
        mesb.append("        return ${varMapper}.updateByPrimaryKeySelective(del_bean);\n");
        //获取内容
        s_Method.setMethodContext(mesb.toString());
        return s_Method;
    }

    /* -------------------------- detail ------------------------- */

    /**
     * 生成控制层接口
     *
     * @return
     */
    public FileInfo.MethodInfo cGenDetailMethod() {
        FileInfo.MethodInfo c_method = new FileInfo.MethodInfo();
        c_method.setMethodName("Detail");
        c_method.setIsRouter(true);
        c_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        c_method.setRefundType(this.ResDtoFileName);
        c_method.setMethodRemark("查询单个" + ToApiMain.BeanChineseName + "对象详情");
        //获取内容
        StringBuilder mesb = new StringBuilder();
        mesb.append("        ${resDtoName} detail = ${varService}.Detail(${inParams});\n");
        mesb.append("        if (detail == null || !detail.getAvailable()) {\n");
        mesb.append("            return SigoResult.fail(\"${BeanChineseName}不存在或已删除\");\n");
        mesb.append("        }\n");
        mesb.append("        detail.setAvailable(false);\n");
        mesb.append("        return detail;\n");
        c_method.setMethodContext(mesb.toString());
        return c_method;
    }

    /**
     * 生成业务接口类
     *
     * @return
     */
    public FileInfo.MethodInfo iGenDetailMethod() {
        FileInfo.MethodInfo i_method = new FileInfo.MethodInfo();
        i_method.setMethodName("Detail");
        i_method.setInParams(SigoListUtils.toList(this.DtoFileName));
        i_method.setRefundType(this.ResDtoFileName);
        i_method.setMethodRemark("查询单个" + ToApiMain.BeanChineseName + "对象详情");
        //获取内容
        return i_method;
    }

    /**
     * 生成业务实现类
     *
     * @return
     */
    public FileInfo.MethodInfo sGenDetailMethod() {

        //添加需要使用的bean
        service_file.getFieldInfoList().add(FileInfo.autoField("UidGenService"));
        service_file.getImportList().add("import " + ToApiMain.ServicePackageUrl + ".UidGenService");
        service_file.getImportList().add("import java.util.Date");

        FileInfo.MethodInfo s_Method = new FileInfo.MethodInfo();
        s_Method.setMethodName("Detail");
        s_Method.setInParams(SigoListUtils.toList(this.DtoFileName));
        s_Method.setRefundType(this.ResDtoFileName);
        StringBuilder mesb = new StringBuilder();
        mesb
                .append("        ${beanName} bean_detail = ${varMapper}.selectByPrimaryKey(${inParams}.get${KeyName}());\n")
                .append("        if (bean_detail == null){\n")
                .append("            return null;\n")
                .append("        }\n")
                .append("        return SiGoBeanUtil.copyToBean_(bean_detail, ${resDtoName}.class);\n")
        ;
        //获取内容
        s_Method.setMethodContext(mesb.toString());
        return s_Method;
    }


    public void genApiFile() {
        initFileInfo();
        genClassFileInfo();
        genList();
        genAdd();
        genEdit();
        genDel();
        genDetail();
        //获取文件对象列表
        for (FileInfo fileInfo : interfaceFileInfoList) {
            File directory = this.getDirectory(ToApiMain.ProjectUrl, ToApiMain.ServicePackageUrl);
            File targetFile = new File(directory, fileInfo.getClassName() + ".java");
            if (!targetFile.exists()) {
                try {
                    targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fileInfoWriteService(targetFile, fileInfo);
        }
        //获取文件对象列表
        for (FileInfo fileInfo : serviceFileInfoList) {
            File directory = this.getDirectory(ToApiMain.ProjectUrl, ToApiMain.ServicePackageUrl + ".impl");
            File targetFile = new File(directory, fileInfo.getClassName() + ".java");
            if (!targetFile.exists()) {
                try {
                    targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fileInfoWriteService(targetFile, fileInfo);
        }
        //获取文件对象列表
        for (FileInfo fileInfo : controllerFileInfoList) {
            File directory = this.getDirectory(ToApiMain.ProjectUrl, ToApiMain.ControllerPackageUrl);
            File targetFile = new File(directory, fileInfo.getClassName() + ".java");
            if (!targetFile.exists()) {
                try {
                    targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fileInfoWriteService(targetFile, fileInfo);
        }

    }

    /**
     * 获取文件路径目录
     *
     * @param projectUrl
     * @param packageUrl
     * @return
     */
    public File getDirectory(String projectUrl, String packageUrl) {
        File project = new File(projectUrl);
        if (!project.isDirectory()) {
            throw new LanpException("项目目录错误，非文件夹");
        }
        StringBuilder sb = new StringBuilder();
        StringTokenizer st = new StringTokenizer(packageUrl, "."); //$NON-NLS-1$
        while (st.hasMoreTokens()) {
            sb.append(st.nextToken());
            sb.append(File.separatorChar);
        }
        File directory = new File(project, sb.toString());
        if (!directory.isDirectory()) {
            boolean rc = directory.mkdirs();
            if (!rc) {
                throw new LanpException("项目目录创建包失败");
            }
        }
        return directory;
    }

    /**
     * 内容输出
     *
     * @param targetFile
     * @param javaFile
     */
    public void fileInfoWriteService(File targetFile, FileInfo javaFile) {
        System.out.println("targetFile:" + targetFile + "   " + "javaFile:" + javaFile);
        StringBuilder fileContext = new StringBuilder();
        fileContext.append("package ").append(javaFile.getPackageName()).append(";\n\n");
        for (String importStr : javaFile.getImportList()) {
            fileContext.append(importStr).append(";\n");
        }
        fileContext.append("\n");
        //作者注释
        fileContext.append("/**\n" +
                " * @author jiangpeng\n" +
                " * Created with IntelliJ IDEA.\n" +
                " * Description: " + javaFile.getAuthorInfo() + "\n" +
                " * Date: " + DateUtils.getNowDateStr() + "\n" +
                " */\n");
        //类注解
        if (CollectionUtil.isNotEmpty(javaFile.getClassAnnotations())) {
            for (String classAnnotation : javaFile.getClassAnnotations()) {
                fileContext.append(classAnnotation).append("\n");
            }
        }
        //类
        fileContext.append("public ")
                .append(javaFile.getJavaType()).append(" ")
                .append(javaFile.getClassName()).append(" ");
        //实现
        if (StringUtils.isNotBlank(javaFile.getImplClassName())) {
            fileContext.append("implements ")
                    .append(javaFile.getImplClassName()).append(" ");
        }
        fileContext.append("{\n");
        //mapper
        FileInfo.FieldInfo myMapperField = javaFile.getMyMapperField();
        if (myMapperField != null) {
            if (myMapperField.getIsAutowired()) {
                fileContext.append("\t@Autowired").append("\n");
            }
            fileContext.append("\t").append(myMapperField.getAccessType()).append(" ");
            fileContext.append(myMapperField.getFieldType()).append(" ");
            fileContext.append(myMapperField.getFieldName()).append(";\n");
        }
        //service
        FileInfo.FieldInfo myServiceField = javaFile.getMyServiceField();
        if (myServiceField != null) {
            if (myServiceField.getIsAutowired()) {
                fileContext.append("\t@Autowired").append("\n");
            }
            fileContext.append("\t").append(myServiceField.getAccessType()).append(" ");
            fileContext.append(myServiceField.getFieldType()).append(" ");
            fileContext.append(myServiceField.getFieldName()).append(";\n");
        }
        //属性
        List<FileInfo.FieldInfo> fieldInfoList = javaFile.getFieldInfoList();
        if (CollectionUtil.isNotEmpty(fieldInfoList)) {
            for (FileInfo.FieldInfo fieldInfo : fieldInfoList) {
                if (fieldInfo.getIsAutowired()) {
                    fileContext.append("\t@Autowired").append("\n");
                }
                fileContext.append("\t");
                fileContext.append(fieldInfo.getAccessType()).append(" ");
                fileContext.append(fieldInfo.getFieldType()).append(" ");
                fileContext.append(fieldInfo.getFieldName()).append(";\n");
            }
        }
        fileContext.append("\n");
        //方法
        List<FileInfo.MethodInfo> methodInfoList = javaFile.getMethodInfoList();
        for (FileInfo.MethodInfo methodInfo : methodInfoList) {
            //注释
            if (StringUtils.isNotBlank(methodInfo.getMethodRemark())) {
                fileContext.append("\t/**\n" +
                        "     * " + methodInfo.getMethodRemark() + "\n" +
                        "     * @return\n" +
                        "     */\n");
            }
            //注解
            if (methodInfo.getIsRouter() != null && methodInfo.getIsRouter()) {
                String apiName = StrUtil.toSymbolCase(methodInfo.getMethodName(), '-');
                fileContext.append("\t@PostMapping(\"" + "/" + apiName + "\")\n");
            }
            if (javaFile.isOverride()) {
                fileContext.append("\t@Override\n");
            }
            fileContext.append("\t");
            if (JavaCSV.Java_Type_class.equals(javaFile.getJavaType())) {
                fileContext.append(methodInfo.getAccessType()).append(" ");
            }
            fileContext.append(methodInfo.getRefundType()).append(" ");
            fileContext.append(methodInfo.getMethodName());
            //入参
            fileContext.append("(");
            if (methodInfo.getIsRouter() != null && methodInfo.getIsRouter()) {
                fileContext.append("@RequestBody ");
            }
            Iterator<String> inParams = methodInfo.getInParams().iterator();
            while (inParams.hasNext()) {
                String inParam = inParams.next();
                fileContext.append(inParam).append(" ").append(SigoStrUtils.getVarName(inParam));
                if (inParams.hasNext()) {
                    fileContext.append(",");
                }
            }
            fileContext.append(")");
            if (JavaCSV.Java_Type_interface.equals(javaFile.getJavaType())) {
                fileContext.append(";\n");
            }
            //内容
            if (StringUtils.isNotBlank(methodInfo.getMethodContext())) {
                fileContext.append("{\n");
                //处理方法内容的占位符
                String methodContext = this.appendMethodContext(javaFile, methodInfo);
                fileContext.append(methodContext);
                fileContext.append("\t}\n\n");
            }
        }
        fileContext.append("}");
        //输出
        try (FileOutputStream fos = new FileOutputStream(targetFile, false)) {
            OutputStreamWriter osw;
            osw = new OutputStreamWriter(fos, "UTF-8");
            try (BufferedWriter bw = new BufferedWriter(osw)) {
                bw.write(fileContext.toString());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public String appendMethodContext(FileInfo javaFile, FileInfo.MethodInfo methodInfo) {
        String methodContext = methodInfo.getMethodContext();
        if (CollectionUtil.isNotEmpty(methodInfo.getInParams())) {
            methodContext = methodContext.replaceAll(JavaCSV.inParams, SigoStrUtils.getVarName(methodInfo.getInParams().get(0)));
        }
        methodContext = methodContext.replaceAll(JavaCSV.example, ExampleFileName);
        methodContext = methodContext.replaceAll(JavaCSV.beanName, BeanFileName);
        methodContext = methodContext.replaceAll(JavaCSV.dtoName, DtoFileName);
        methodContext = methodContext.replaceAll(JavaCSV.resDtoName, ResDtoFileName);
        methodContext = methodContext.replaceAll(JavaCSV.KeyName, SigoStrUtils.getGetMethodName(ToApiMain.KeyName));
        methodContext = methodContext.replaceAll(JavaCSV.key_name, SigoStrUtils.toUnderlineCase(ToApiMain.KeyName));
        methodContext = methodContext.replaceAll(JavaCSV.BeanChineseName, SigoStrUtils.toUnderlineCase(ToApiMain.BeanChineseName));
        if (javaFile.getMyMapperField() != null) {
            methodContext = methodContext.replaceAll(JavaCSV.varMapper, javaFile.getMyMapperField().getFieldName());
        }
        if (javaFile.getMyServiceField() != null) {
            methodContext = methodContext.replaceAll(JavaCSV.varService, javaFile.getMyServiceField().getFieldName());
        }
        return methodContext;
    }
}